package com.wider.foundation;


import java.io.PrintStream;
import java.util.Set;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * This class defines the Root interface for user to manage the DLogger.
 * @author William
 */
public class DLoggerRoot extends DLogger{
    /**
     * Constructor. User MUST call <code>DLogger.getRoot()</code> to get the Root interface rather than calling the default constrcutor.
     */
    public DLoggerRoot(){
        super("ROOT");
    }

    /**
     * Method for the Main program to set the output PrintStream
     * @param stream    The desired output PrintStream
     */
    public void setStream(PrintStream stream){
        DLogger.pstream = stream;
    }

    /**
     * Method for user to enable the logging through using the DLogger.
     * @return  True if enabled; false otherwise.
     */
    public boolean enable(){
        if (null != DLogger.pstream)
            DLogger.enabled = true;
        
        return DLogger.isEnabled();
    }

    /**
     * Method for user to disable the logging service provided by the DLogger.
     * @return  True if disabled; false otherwise.
     */
    public boolean disable(){
        DLogger.enabled = false;
        return DLogger.isEnabled();
    }

    /**
     * Method for user to set the overall output base level.
     * @param level     Base logging level
     */
    @Override
    public void setLevel(DLevel level){
        DLogger.rootbound = level;
        super.setLevel(level);
        for (String classname : classeslevel.keySet()){
            setLevel(classname, level);
        }
    }

    /**
     * Method for user to set the base level at Class or Instance perspective.
     * @param ref       The reference of an Named instance, or a Class. As well as a String of a class name, or an object representing a class.
     * @param level     The desired base level.
     */
    public void setLevel(Object ref, DLevel level){
        String cname = null;
        String iname = null;

        if (ref instanceof Named){
            iname = ((Named) ref).getName();
        }else if (ref instanceof Class){
            cname = ((Class) ref).getName();
        }else if (ref instanceof String){
            cname = (String) ref;
        }else {
            cname = ref.getClass().getName();
        }

        if (null != cname)
            setClassLevel(cname, level);
        else if (null != iname)
            setInstanceLevel(iname, level);

    }

    /**
     * Method for user to get the current level at Class or Instance.
     * @param ref       The reference of an Named instance, or a Class. As well as a String of a class name, or an object representing a class.
     */
    public DLevel getLevel(Object ref){
        String cname = null;
        String iname = null;

        if (ref instanceof Named){
            iname = ((Named) ref).getName();
        }else if (ref instanceof Class){
            cname = ((Class) ref).getName();
        }else if (ref instanceof String){
            cname = (String) ref;
        }else {
            cname = ref.getClass().getName();
        }

        if (null != iname)
            return getInstanceLevel(iname);
        else
            return getClassLevel(cname);
    }

    private void setInstanceLevel(String id, DLevel level){
        DLogger logger = instancesmap.get(id);
        if (null != logger)
            logger.setLevel(level);
    }

    private void setClassLevel(String class_name, DLevel level){
        classeslevel.remove(class_name);
        classeslevel.put(class_name, level);
        Set<String> instances = classesmap.get(class_name);
        for (String instance : instances){
            setInstanceLevel(instance, level);
        }
    }

    private DLevel getClassLevel(String class_name){
        return classeslevel.get(class_name);
    }

    private DLevel getInstanceLevel(String id){
        DLogger logger = instancesmap.get(id);
        if (null != logger)
            return logger.getLevel();
        else
            return null;
    }


}
